home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_084 / ed / amatch.c next >
C/C++ Source or Header  |  1992-05-06  |  3KB  |  105 lines

  1. #include <stdio.h>
  2. #include "tools.h"
  3.  
  4. /*     Scans throught the pattern template looking for a match
  5.  * with lin.  Each element of lin is compared with the template
  6.  * until either a mis-match is found or the end of the template
  7.  * is reached.  In the former case a 0 is returned; in the latter,
  8.  * a pointer into lin (pointing to the character following the
  9.  * matched pattern) is returned.
  10.  *
  11.  *    "lin"    is a pointer to the line being searched.
  12.  *    "pat"    is a pointer to a template made by makepat().
  13.  *    "boln"    is a pointer into "lin" which points at the
  14.  *            character at the beginning of the line.
  15.  */
  16. char    *
  17. amatch(lin, pat, boln)
  18. char    *lin;
  19. TOKEN    *pat;
  20. char    *boln;
  21. {
  22.     register char    *bocl, *rval, *strstart;
  23.  
  24.     if(pat == 0)
  25.         return 0;
  26.  
  27.     strstart = lin;
  28.  
  29.     while(pat)
  30.     {
  31.         if(pat->tok == CLOSURE && pat->next)
  32.         {
  33.                 /* Process a closure:
  34.                  * first skip over the closure token to the
  35.                  * object to be repeated.  This object can be
  36.                  * a character class.
  37.                  */
  38.  
  39.             pat = pat->next;
  40.  
  41.                 /* Now match as many occurrences of the
  42.                  * closure pattern as possible.
  43.                  */
  44.             bocl = lin;
  45.  
  46.             while( *lin && omatch(&lin, pat))
  47.                 ;
  48.  
  49.                 /* 'Lin' now points to the character that made
  50.                  * made us fail.  Now go on to process the
  51.                  * rest of the string.  A problem here is
  52.                  * a character following the closure which
  53.                  * could have been in the closure.
  54.                  * For example, in the pattern "[a-z]*t" (which
  55.                  * matches any lower-case word ending in a t),
  56.                  * the final 't' will be sucked up in the while
  57.                  * loop.  So, if the match fails, we back up a
  58.                  * notch and try to match the rest of the
  59.                  * string again, repeating this process
  60.                  * recursively until we get back to the
  61.                  * beginning of the closure.  The recursion
  62.                  * goes, at most two levels deep.
  63.                  */
  64.  
  65.             if(pat = pat->next)
  66.             {
  67.                 while(bocl <= lin)
  68.                 {
  69.                     if(rval = amatch(lin, pat, boln))
  70.                     {
  71.                             /* success */
  72.                         return(rval);
  73.                     } else
  74.                         --lin;
  75.                 }
  76.                 return (0);    /* match failed */
  77.             }
  78.         } else if (omatch(&lin, pat, boln))
  79.         {
  80.             pat = pat->next;
  81.         } else {
  82.             return (0);
  83.         }
  84.     }
  85.         /* Note that omatch() advances lin to point at the next
  86.          * character to be matched.  Consequently, when we reach
  87.          * the end of the template, lin will be pointing at the
  88.          * character following the last character matched.  The
  89.          * exceptions are templates containing only a BOLN or EOLN
  90.          * token.  In these cases omatch doesn't advance.
  91.          *
  92.          * A philosophical point should be mentioned here.  Is $
  93.          * a position or a character? (i.e. does $ mean the EOL
  94.          * character itself or does it mean the character at the end
  95.          * of the line.)  I decided here to make it mean the former,
  96.          * in order to make the behavior of amatch() consistent.  If
  97.          * you give amatch the pattern ^$ (match all lines consisting
  98.          * only of an end of line) then, since something has to be
  99.          * returned, a pointer to the end of line character itself is
  100.          * returned.
  101.          */
  102.  
  103.     return ((char *)max(strstart , lin));
  104. }
  105.